home *** CD-ROM | disk | FTP | other *** search
- // IconWellControl.m
- //
- // Free software created 1 Feb 1992
- // by Paul Burchard <burchard@math.utah.edu>.
-
- #import "IconWellControl.h"
- #import "IconWell.h"
- #import "DragDrop.h"
- #import <appkit/appkit.h>
- #import <objc/Storage.h>
- #import <objc/HashTable.h>
-
-
- @implementation IconWellControl
-
- static id wellSpeaker;
- static id convertWindowToControl;
-
- + initialize
- {
- if(self == [IconWellControl class])
- {
- wellSpeaker = [[Speaker alloc] init];
- convertWindowToControl =
- [[HashTable alloc] initKeyDesc:"@" valueDesc:"@"];
- }
- return self;
- }
-
- + controlFor:theWindow
- {
- return (id)[convertWindowToControl valueForKey:(void *)theWindow];
- }
-
- - listen:sender
- {
- // Tell WorkSpace we want icon-dragging.
- if(isListening) return self;
- if(!window) return nil;
- NXConvertWinNumToGlobal([window windowNum], &globalWindowNum);
- if(![wellSpeaker setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)])
- return nil;
- if(0 != [wellSpeaker registerWindow:globalWindowNum
- toPort:[wellListener listenPort]])
- return nil;
- [wellListener setDelegate:self];
- isListening = YES;
- return self;
- }
-
- - initWindow:theWindow
- {
- char portName[1024];
-
- [super init];
- window = theWindow;
- wellListener = [[Listener alloc] init];
- sprintf(portName, "IconWellControlPort-%ld", (long)[self self]);
- if(0 != [wellListener checkInAs:portName]) return nil;
- [wellListener addPort];
- newIconPath = [[Storage alloc] initCount:0 elementSize:sizeof(char) description:"c"];
- [convertWindowToControl insertKey:(void *)theWindow value:(void *)self];
- [self listen:self];
- return self;
- }
-
- - free
- {
- if(window) [convertWindowToControl removeKey:(void *)window];
- [wellListener free];
- [newIconPath free];
- [newIconImage free];
- return [super free];
- }
-
- - (const char *)newIconPath
- {
- return (const char *)[newIconPath elementAt:0];
- }
-
- - (int)iconEntered:(int)windowNum at:(double)x :(double)y
- iconWindow:(int)iconWindowNum iconX:(double)iconX iconY:(double)iconY
- iconWidth:(double)iconWidth iconHeight:(double)iconHeight
- pathList:(char *)pathList
- {
- int i, n;
- id list;
- NXSize size;
-
- // Create temp NXImage to hold dragged icon.
- // NOTE: newIconImage is only freed beforehand if it still has temp name.
- if(!pathList) return 0;
- size.width = size.height = 48.0;
- [[NXImage findImageNamed:newIconName] free];
- newIconImage = [[NXImage alloc] initSize:&size];
- [newIconImage lockFocus];
- copyIconPicture(iconWindowNum,
- (float) iconX, (float) iconY, (float) iconWidth, (float) iconHeight);
- [newIconImage unlockFocus];
- [newIconImage setName:newIconName];
-
- // Temporarily stash new path.
- [newIconPath setNumSlots:(strlen(pathList)+1)];
- strcpy((char *)[newIconPath elementAt:0], pathList);
-
- // Accept message, and forward to all IconWells in this Window.
- list = [IconWell wellListFor:window];
- n = [list count];
- for(i=0; i<n; i++)
- [[list objectAt:i] iconEntered:windowNum at:x :y
- iconWindow:iconWindowNum iconX:iconX iconY:iconY
- iconWidth:iconWidth iconHeight:iconHeight
- pathList:pathList];
- return 0;
- }
-
- - (int)iconMovedTo:(double)x :(double)y
- {
- int i, n;
- id list;
-
- // Accept message, and forward to all IconWells in this Window.
- list = [IconWell wellListFor:window];
- n = [list count];
- for(i=0; i<n; i++)
- [[list objectAt:i] iconMovedTo:x :y];
- return 0;
- }
-
- - (int)iconExitedAt:(double)x :(double)y
- {
- int i, n;
- id list;
-
- // Accept message, and forward to all IconWells in this Window.
- list = [IconWell wellListFor:window];
- n = [list count];
- for(i=0; i<n; i++)
- [[list objectAt:i] iconExitedAt:x :y];
-
- // Get rid of temp icon and path.
- [[NXImage findImageNamed:newIconName] free];
- newIconImage = nil;
- [newIconPath setNumSlots:0];
- return 0;
- }
-
- - (int)iconReleasedAt:(double)x :(double)y ok:(int *)flag
- {
- int i, n, accepted;
- id list;
-
- // Accept message, and forward to all IconWells in this Window.
- list = [IconWell wellListFor:window];
- n = [list count];
- for(i=0, *flag=0, accepted=0; i<n; i++, accepted=0)
- {
- [[list objectAt:i] iconReleasedAt:x :y ok:&accepted];
- if(accepted != 0) *flag = 1;
- }
-
- // Get rid of temp path.
- // Temp icon image is only freed if it was not accepted.
- [newIconPath setNumSlots:0];
- if(*flag == 0)
- {
- [[NXImage findImageNamed:newIconName] free];
- newIconImage = nil;
- }
- return 0;
- }
-
- @end
-